package com.bubblegumproject.ogo.remote.tunnel;

import com.bubblegumproject.ogo.remote.RemoteReactor;
import com.bubblegumproject.ogo.remote.RemoteReactorException;
import com.bubblegumproject.ogo.remote.io.ActionPacketFactory;
import com.bubblegumproject.ogo.remote.io.DefaultActionPacketFactory;
import com.bubblegumproject.ogo.remote.io.ActionPacket;
import com.bubblegumproject.ogo.action.Action;
import org.apache.log4j.Logger;

/**
 * Reactor that will send Action requests using a Tunnel to a remote reactor.
 *
 * @author Azubuko Obele (buko.obele@gmail.com)
 */
public class TunnelRemoteReactor implements RemoteReactor {

    private Tunnel tunnel;

    private TunnelClient client;

    private ActionPacketFactory packetFactory = new DefaultActionPacketFactory();

    private static final Logger log = Logger.getLogger(TunnelRemoteReactor.class);

    public TunnelRemoteReactor(Tunnel tunnel, TunnelClient client) {
        assert (tunnel != null && client != null);
        this.tunnel = tunnel;
        this.client = client;
    }

    public Action react(Action action) {
        assert (action != null);
        ActionPacket input = packetFactory.createInputPacket(action);
        log.debug(this + " created ActionPacket input=" + input);
        TunnelRequest request = new TunnelRequest(input, client);
        TunnelResponse response = tunnel.send(request);
        if (!response.remoteErrorOccurred()) {
            log.debug(this + " received ActionPacket output=" + response.getOutputPacket());
            Action output = packetFactory.parseOutputPacket(response.getOutputPacket());
            return output;
        } else {
            throw new RemoteReactorException(response.getRemoteReactorError());
        }
    }
}
